package com.zhangxi.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zhangxi.constant.MessageConstant;
import com.zhangxi.constant.StatusConstant;
import com.zhangxi.dto.SetMealDTO;
import com.zhangxi.dto.SetMealPageQueryDTO;
import com.zhangxi.entity.Dish;
import com.zhangxi.entity.SetMeal;
import com.zhangxi.entity.SetMealDish;
import com.zhangxi.exception.DeletionNotAllowedException;
import com.zhangxi.exception.SetMealEnableFailedException;
import com.zhangxi.mapper.DishMapper;
import com.zhangxi.mapper.SetMealDishMapper;
import com.zhangxi.mapper.SetMealMapper;
import com.zhangxi.result.PageResult;
import com.zhangxi.service.SetMealService;
import com.zhangxi.vo.DishItemVO;
import com.zhangxi.vo.DishVo;
import com.zhangxi.vo.SetMealVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * ClassName: SetMealServiceImpl
 * Package: com.zhangxi.service.impl
 */
@Service
@Slf4j

public class SetMealServiceImpl implements SetMealService {


    @Autowired
    private SetMealMapper setMealMapper;


    @Autowired
    private SetMealDishMapper setMealDishMapper;


    @Autowired
    private DishMapper dishMapper;

    /**
     * 分页查询套餐
     *
     * @param setMealPageQueryDTO
     * @return
     */
    @Override
    public PageResult page(SetMealPageQueryDTO setMealPageQueryDTO) {
        //定义分页
        PageHelper.startPage(setMealPageQueryDTO.getPage(), setMealPageQueryDTO.getPageSize());
        //执行查询操作
        Page<SetMealVo> setMeals = setMealMapper.page(setMealPageQueryDTO);
        //返回封装好的结果
        return new PageResult(setMeals.getTotal(), setMeals.getResult());

    }

    /**
     * 新增套餐
     *
     * @param setMealDTO
     */

    @Transactional
    @Override
    public void insertSetMeal(SetMealDTO setMealDTO) {
        SetMeal setMeal = new SetMeal();
        BeanUtils.copyProperties(setMealDTO, setMeal);
        log.info("新增SetMeal：{}", setMeal);
        //执行插入套餐表操作
        setMealMapper.insert(setMeal);
        List<SetMealDish> setMealDishes = setMealDTO.getSetmealDishes();

        Long setMealId = setMeal.getId();
        //判断是否为空
        if (setMealDishes != null && setMealDishes.size() > 0) {
            //赋值套餐id
            for (SetMealDish setMealDish : setMealDishes) {
                setMealDish.setSetmealId(setMealId);
            }
            //执行批量插入套餐菜品表
            setMealDishMapper.insertBatch(setMealDishes);
        }
    }

    /**
     * 根据id查询套餐信息
     *
     * @param id
     * @return
     */
    @Override
    public SetMealVo getBySetMealId(Long id) {
        //根据id查询出套餐信息
        SetMeal setMeal = setMealMapper.getById(id);
        SetMealVo setMealVo = new SetMealVo();
        //完成属性的拷贝
        BeanUtils.copyProperties(setMeal, setMealVo);
        //根据套餐id查询出菜品
        List<SetMealDish> setMealDishes = setMealDishMapper.getSetMealDishBySetMealId(id);
        //赋值
        setMealVo.setSetmealDishes(setMealDishes);
        return setMealVo;
    }

    /**
     * 修改套餐信息
     *
     * @param setMealDTO
     */
    @Transactional
    @Override
    public void updateSetMeal(SetMealDTO setMealDTO) {
        SetMeal setMeal = new SetMeal();
        //完成属性拷贝
        BeanUtils.copyProperties(setMealDTO, setMeal);
        //修改套餐信息
        setMealMapper.update(setMeal);
        List<SetMealDish> setMealDishes = setMealDTO.getSetmealDishes();
        // 判断是否套餐中含有菜品
        if (setMealDishes != null && setMealDishes.size() > 0) {
            //删除套餐菜品中的原有数据
            setMealDishMapper.deleteBySetMealId(setMeal.getId());
            //再重新添加
            for (SetMealDish setMealDish : setMealDishes) {
                //赋值套餐id
                setMealDish.setSetmealId(setMeal.getId());
            }
            //重新添加n条套餐菜品
            setMealDishMapper.insertBatch(setMealDishes);
        }
    }

    /**
     * 根据id改变套餐的起售状态
     *
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //需要判断起售套餐时，里面不含停售状态的菜品
        if (status == StatusConstant.ENABLE) {
            List<Dish> dishes = dishMapper.getBySetMealId(id);
            for (Dish dish : dishes) {
                //常量写在前是以防里面未含菜品
                if (StatusConstant.DISABLE == dish.getStatus()) {
                    throw new SetMealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                }
            }
        }

        //构建者模式创建
        SetMeal setMeal = SetMeal.builder()
                .status(status)
                .id(id)
                .build();
        //更新操作
        setMealMapper.update(setMeal);
    }

    /**
     * 根据id集合批量删除套餐
     *
     * @param ids
     */
    @Override
    @Transactional
    public void deleteBySetMealId(List<Long> ids) {
        //判断删除的套餐是否为空
        if (ids.isEmpty()){
            //未勾选套餐
            throw new DeletionNotAllowedException(MessageConstant.SETMEALID_NULL);
        }
        //现根据id判断是否为起售状态
        for (Long id : ids) {
            SetMeal setMeal = setMealMapper.getById(id);
            if (StatusConstant.ENABLE ==  setMeal.getStatus() ) {
                //"起售中的套餐不能删除"
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
            }
        }

        //执行删除套餐表操作
        setMealMapper.delete(ids);
        //执行删除套餐菜单表操作
        for (Long id :ids ){
            setMealDishMapper.deleteBySetMealId(id);
        }
    }

    @Override
    public List<SetMeal> list(SetMeal setMeal) {
        return setMealMapper.list(setMeal);
    }


    /**
     * 根据id查询菜品选项
     * @param id
     * @return
     */
    public List<DishItemVO> getDishItemById(Long id) {
        return setMealMapper.getDishItemBySetmealId(id);
    }
}
